home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / fcntlmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  7.1 KB  |  332 lines

  1. /* fcntl module */
  2.  
  3. #include "Python.h"
  4.  
  5. #ifdef HAVE_UNISTD_H
  6. #include <unistd.h>
  7. #endif
  8.  
  9. #ifdef HAVE_SYS_FILE_H
  10. #include <sys/file.h>
  11. #endif
  12.  
  13. #include <sys/ioctl.h>
  14. #include <fcntl.h>
  15.  
  16.  
  17. /* fcntl(fd, opt, [arg]) */
  18.  
  19. static PyObject *
  20. fcntl_fcntl(self, args)
  21.     PyObject *self; /* Not used */
  22.     PyObject *args;
  23. {
  24.     int fd;
  25.     int code;
  26.     int arg;
  27.     int ret;
  28.     char *str;
  29.     int len;
  30.     char buf[1024];
  31.  
  32.     if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
  33.         if (len > sizeof buf) {
  34.             PyErr_SetString(PyExc_ValueError,
  35.                     "fcntl string arg too long");
  36.             return NULL;
  37.         }
  38.         memcpy(buf, str, len);
  39.         Py_BEGIN_ALLOW_THREADS
  40.         ret = fcntl(fd, code, buf);
  41.         Py_END_ALLOW_THREADS
  42.         if (ret < 0) {
  43.             PyErr_SetFromErrno(PyExc_IOError);
  44.             return NULL;
  45.         }
  46.         return PyString_FromStringAndSize(buf, len);
  47.     }
  48.  
  49.     PyErr_Clear();
  50.     if (PyArg_Parse(args, "(ii)", &fd, &code))
  51.         arg = 0;
  52.     else {
  53.         PyErr_Clear();
  54.         if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
  55.             return NULL;
  56.     }
  57.     Py_BEGIN_ALLOW_THREADS
  58.     ret = fcntl(fd, code, arg);
  59.     Py_END_ALLOW_THREADS
  60.     if (ret < 0) {
  61.         PyErr_SetFromErrno(PyExc_IOError);
  62.         return NULL;
  63.     }
  64.     return PyInt_FromLong((long)ret);
  65. }
  66.  
  67. static char fcntl_doc [] =
  68.  
  69. "fcntl(fd, opt, [arg])\n\
  70. \n\
  71. Perform the requested operation on file descriptor fd.  The operation\n\
  72. is defined by op and is operating system dependent.  Typically these\n\
  73. codes can be retrieved from the library module FCNTL.  The argument arg\n\
  74. is optional, and defaults to 0; it may be an int or a string.";
  75.  
  76.  
  77. /* ioctl(fd, opt, [arg]) */
  78.  
  79. static PyObject *
  80. fcntl_ioctl(self, args)
  81.     PyObject *self; /* Not used */
  82.     PyObject *args;
  83. {
  84.     int fd;
  85.     int code;
  86.     int arg;
  87.     int ret;
  88.     char *str;
  89.     int len;
  90.     char buf[1024];
  91.  
  92.     if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
  93.         if (len > sizeof buf) {
  94.             PyErr_SetString(PyExc_ValueError,
  95.                     "ioctl string arg too long");
  96.             return NULL;
  97.         }
  98.         memcpy(buf, str, len);
  99.         Py_BEGIN_ALLOW_THREADS
  100.         ret = ioctl(fd, code, buf);
  101.         Py_END_ALLOW_THREADS
  102.         if (ret < 0) {
  103.             PyErr_SetFromErrno(PyExc_IOError);
  104.             return NULL;
  105.         }
  106.         return PyString_FromStringAndSize(buf, len);
  107.     }
  108.  
  109.     PyErr_Clear();
  110.     if (PyArg_Parse(args, "(ii)", &fd, &code))
  111.         arg = 0;
  112.     else {
  113.         PyErr_Clear();
  114.         if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
  115.             return NULL;
  116.     }
  117.     Py_BEGIN_ALLOW_THREADS
  118.     ret = ioctl(fd, code, arg);
  119.     Py_END_ALLOW_THREADS
  120.     if (ret < 0) {
  121.         PyErr_SetFromErrno(PyExc_IOError);
  122.         return NULL;
  123.     }
  124.     return PyInt_FromLong((long)ret);
  125. }
  126.  
  127. static char ioctl_doc [] =
  128. "ioctl(fd, opt, [arg])\n\
  129. \n\
  130. Perform the requested operation on file descriptor fd.  The operation\n\
  131. is defined by op and is operating system dependent.  Typically these\n\
  132. codes can be retrieved from the library module IOCTL.  The argument arg\n\
  133. is optional, and defaults to 0; it may be an int or a string.";
  134.  
  135.  
  136. /* flock(fd, operation) */
  137.  
  138. static PyObject *
  139. fcntl_flock(self, args)
  140.     PyObject *self; /* Not used */
  141.     PyObject *args;
  142. {
  143.     int fd;
  144.     int code;
  145.     int ret;
  146.  
  147.     if (!PyArg_Parse(args, "(ii)", &fd, &code))
  148.         return NULL;
  149.  
  150. #ifdef HAVE_FLOCK
  151.     Py_BEGIN_ALLOW_THREADS
  152.     ret = flock(fd, code);
  153.     Py_END_ALLOW_THREADS
  154. #else
  155.  
  156. #ifndef LOCK_SH
  157. #define LOCK_SH        1    /* shared lock */
  158. #define LOCK_EX        2    /* exclusive lock */
  159. #define LOCK_NB        4    /* don't block when locking */
  160. #define LOCK_UN        8    /* unlock */
  161. #endif
  162.     {
  163.         struct flock l;
  164.         if (code == LOCK_UN)
  165.             l.l_type = F_UNLCK;
  166.         else if (code & LOCK_SH)
  167.             l.l_type = F_RDLCK;
  168.         else if (code & LOCK_EX)
  169.             l.l_type = F_WRLCK;
  170.         else {
  171.             PyErr_SetString(PyExc_ValueError,
  172.                     "unrecognized flock argument");
  173.             return NULL;
  174.         }
  175.         l.l_whence = l.l_start = l.l_len = 0;
  176.         Py_BEGIN_ALLOW_THREADS
  177.         ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
  178.         Py_END_ALLOW_THREADS
  179.     }
  180. #endif /* HAVE_FLOCK */
  181.     if (ret < 0) {
  182.         PyErr_SetFromErrno(PyExc_IOError);
  183.         return NULL;
  184.     }
  185.     Py_INCREF(Py_None);
  186.     return Py_None;
  187. }
  188.  
  189. static char flock_doc [] =
  190. "flock(fd, operation)\n\
  191. \n\
  192. Perform the lock operation op on file descriptor fd.  See the Unix \n\
  193. manual flock(3) for details.  (On some systems, this function is\n\
  194. emulated using fcntl().)";
  195.  
  196.  
  197. /* lockf(fd, operation) */
  198. static PyObject *
  199. fcntl_lockf(self, args)
  200.     PyObject *self; /* Not used */
  201.     PyObject *args;
  202. {
  203.     int fd, code, ret, whence = 0;
  204.     PyObject *lenobj = NULL, *startobj = NULL;
  205.  
  206.     if (!PyArg_ParseTuple(args, "ii|OOi:lockf", &fd, &code,
  207.                   &lenobj, &startobj, &whence))
  208.         return NULL;
  209.  
  210. #ifndef LOCK_SH
  211. #define LOCK_SH        1    /* shared lock */
  212. #define LOCK_EX        2    /* exclusive lock */
  213. #define LOCK_NB        4    /* don't block when locking */
  214. #define LOCK_UN        8    /* unlock */
  215. #endif
  216.     {
  217.         struct flock l;
  218.         if (code == LOCK_UN)
  219.             l.l_type = F_UNLCK;
  220.         else if (code & LOCK_SH)
  221.             l.l_type = F_RDLCK;
  222.         else if (code & LOCK_EX)
  223.             l.l_type = F_WRLCK;
  224.         else {
  225.             PyErr_SetString(PyExc_ValueError,
  226.                     "unrecognized flock argument");
  227.             return NULL;
  228.         }
  229.         l.l_start = l.l_len = 0;
  230.         if (startobj != NULL) {
  231. #if !defined(HAVE_LARGEFILE_SUPPORT)
  232.             l.l_start = PyInt_AsLong(startobj);
  233. #else
  234.             l.l_start = PyLong_Check(startobj) ?
  235.                     PyLong_AsLongLong(startobj) :
  236.                     PyInt_AsLong(startobj);
  237. #endif
  238.             if (PyErr_Occurred())
  239.                 return NULL;
  240.         }
  241.         if (lenobj != NULL) {
  242. #if !defined(HAVE_LARGEFILE_SUPPORT)
  243.             l.l_len = PyInt_AsLong(lenobj);
  244. #else
  245.             l.l_len = PyLong_Check(lenobj) ?
  246.                     PyLong_AsLongLong(lenobj) :
  247.                     PyInt_AsLong(lenobj);
  248. #endif
  249.             if (PyErr_Occurred())
  250.                 return NULL;
  251.         }
  252.         l.l_whence = whence;
  253.         Py_BEGIN_ALLOW_THREADS
  254.         ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
  255.         Py_END_ALLOW_THREADS
  256.     }
  257.     if (ret < 0) {
  258.         PyErr_SetFromErrno(PyExc_IOError);
  259.         return NULL;
  260.     }
  261.     Py_INCREF(Py_None);
  262.     return Py_None;
  263. }
  264.  
  265. static char lockf_doc [] =
  266. "lockf (fd, operation)\n\
  267. \n\
  268. This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
  269. calls.  See the Unix manual for details.";
  270.  
  271. /* List of functions */
  272.  
  273. static PyMethodDef fcntl_methods[] = {
  274.     {"fcntl",    fcntl_fcntl, 0, fcntl_doc},
  275.     {"ioctl",    fcntl_ioctl, 0, ioctl_doc},
  276.     {"flock",    fcntl_flock, 0, flock_doc},
  277.     {"lockf",       fcntl_lockf, 1, lockf_doc},
  278.     {NULL,        NULL}        /* sentinel */
  279. };
  280.  
  281.  
  282. static char module_doc [] =
  283.  
  284. "This module performs file control and I/O control on file \n\
  285. descriptors.  It is an interface to the fcntl() and ioctl() Unix\n\
  286. routines.  File descriptors can be obtained with the fileno() method of\n\
  287. a file or socket object.";
  288.  
  289. /* Module initialisation */
  290.  
  291. static int
  292. ins(d, symbol, value)
  293.         PyObject* d;
  294.         char* symbol;
  295.         long value;
  296. {
  297.         PyObject* v = PyInt_FromLong(value);
  298.         if (!v || PyDict_SetItemString(d, symbol, v) < 0)
  299.                 return -1;
  300.  
  301.         Py_DECREF(v);
  302.         return 0;
  303. }
  304.  
  305. static int
  306. all_ins(d)
  307.         PyObject* d;
  308. {
  309.         if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
  310.         if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
  311.         if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
  312.         if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
  313.     return 0;
  314. }
  315.  
  316. DL_EXPORT(void)
  317. initfcntl()
  318. {
  319.     PyObject *m, *d;
  320.  
  321.     /* Create the module and add the functions and documentation */
  322.     m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
  323.  
  324.     /* Add some symbolic constants to the module */
  325.     d = PyModule_GetDict(m);
  326.     all_ins(d);
  327.  
  328.     /* Check for errors */
  329.     if (PyErr_Occurred())
  330.         Py_FatalError("can't initialize module fcntl");
  331. }
  332.